package com.hospital.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hospital.domain.pojo.*;
import com.hospital.domain.utils.Result;
import com.hospital.mapper.DepMapper;
import com.hospital.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;

@Service
@RequiredArgsConstructor
public class DepServiceImpl extends ServiceImpl<DepMapper, Department> implements DepService {

    private final ScheduleService scheduleService;
    private final ReservationService reservationService;
    private final MedicalRecordService medicalRecordService;
    private final DepMapper depMapper;

    private DoctorService doctorService;

    @Autowired
    public void setDoctorService(@Lazy DoctorService doctorService) {
        this.doctorService = doctorService;
    }
    @Transactional
    @Override
    public Result removeDep(Integer depId) {

        List<Doctor> doctors = doctorService.lambdaQuery().eq(Doctor::getDepId, depId).list();
        HashSet<Integer> doctorIds = new HashSet<>();
        for(Doctor d : doctors){
            doctorIds.add(d.getDId());
        }

        List<Schedule> schedules1 = scheduleService.lambdaQuery().in(!doctorIds.isEmpty(), Schedule::getDId, doctorIds).list();
        List<Schedule> schedules2 = scheduleService.lambdaQuery().eq(Schedule::getDepId, depId).list();
        HashSet<Integer> scheduleIds = new HashSet<>();
        for(Schedule s : schedules1){
            scheduleIds.add(s.getSId());
        }
        for(Schedule s : schedules2){
            scheduleIds.add(s.getSId());
        }

        List<Reservation> reservations = reservationService.lambdaQuery().in(Reservation::getSId, scheduleIds).list();
        HashSet<Integer> reservationIds = new HashSet<>();
        for(Reservation r : reservations){
            reservationIds.add(r.getRId());
        }
        //删除就诊记录表中与该预约记录有关的数据
        if(!reservationIds.isEmpty()){
            LambdaQueryWrapper<MedicalRecord> w4 = new QueryWrapper<MedicalRecord>().lambda().in(MedicalRecord::getRId, reservationIds);
            medicalRecordService.remove(w4);
        }

        //删除预约记录表中与该出诊安排有关的数据
        if(!scheduleIds.isEmpty()){
            LambdaQueryWrapper<Reservation> w3 = new QueryWrapper<Reservation>().lambda().in(Reservation::getSId, scheduleIds);
            reservationService.remove(w3);
        }
        //删除出诊安排表中与该科室和医生有关的数据

        if(!doctorIds.isEmpty()){
            LambdaQueryWrapper<Schedule> w5 = new QueryWrapper<Schedule>().lambda().in(Schedule::getDId, doctorIds).or().eq(Schedule::getDepId, depId);
            scheduleService.remove(w5);
        }

        //删除医生表中与该科室有关的数据
        if(!doctorIds.isEmpty()){
            doctorService.removeByIds(doctorIds);
        }

        //删除科室
        removeById(depId);

        return Result.ok("删除成功");
    }

    @Override
    public Result queryDep() {
        List<Department> departments = list();
        return Result.ok(departments);
    }

    @Override
    public Result addDep(String name, String info, String level, String phone) {
        if(lambdaQuery().eq(Department::getDepName, name).exists()){
            return Result.fail("该科室已存在");
        }
        if(lambdaQuery().eq(Department::getDepPhone, phone).exists()){
            return Result.fail("该电话已被使用");
        }
        save(new Department(name, info, level, phone));
        return Result.ok("新增成功");
    }

    @Override
    public Result updateDep(Integer depId, String name, String info, String level, String phone) {
        if(lambdaQuery().eq(Department::getDepName, name).exists()){
            return Result.fail("该科室已存在");
        }
        if(lambdaQuery().eq(Department::getDepPhone, phone).exists()){
            return Result.fail("该电话已被使用");
        }
        depMapper.updateDep(name, info, level, phone, depId);
        return Result.ok("编辑成功");
    }
}
